<template>
  <div>
    <el-card class="box-card" v-loading.fullscreen.lock="fullscreenLoading">
      <div slot="header" class="card-header">
        <div style="width: 100%;">
          <div style="width: 100%;height: 50px;text-align: center;">
            <el-button @click="startRecorder()" style="margin-left: -150px;margin-right: 15px;">开始识音</el-button>
            <el-button @click="stopRecorder()" style="margin-left: 15px;margin-right: 15px;">结束识音</el-button>
          </div>
          <div style="width:100%;height:150px;border:1px solid #ddd;border-radius: 5px;">
            <canvas id="canvas"></canvas>
            <span style="padding: 0 10%;"></span>
            <canvas id="playChart"></canvas>
          </div>
        </div>
      </div>
      <div class="text item card-wenzi-item">
        <div v-html="message"></div>
      </div>
    </el-card>
  </div>
</template>
<script>
import Recorder from 'js-audio-recorder'
import { VoiceUploadfiles } from "@/api/power/voice"
const recorder = new Recorder({
  sampleBits: 16,                 // 采样位数，支持 8 或 16，默认是16
  sampleRate: 48000,              // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
  numChannels: 1,                 // 声道，支持 1 或 2， 默认是1
  // compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换，默认是false
})
// 绑定事件-打印的是当前录音数据
recorder.onprogress = function (params) {
  /*
  console.log('--------------START---------------')
  console.log('录音时长(秒)', params.duration);
  console.log('录音大小(字节)', params.fileSize);
  console.log('录音音量百分比(%)', params.vol);
  console.log('当前录音的总数据([DataView, DataView...])', params.data);
  console.log('--------------END---------------')
  */
}
export default {
  name: 'home',
  data() {
    return {
      //波浪图-录音
      drawRecordId: null,
      oCanvas: null,
      ctx: null,
      //波浪图-播放
      drawPlayId: null,
      pCanvas: null,
      pCtx: null,
      message: "",
      maxDuration: 3600000,
      fullscreenLoading: false
    }
  },
  mounted() {
    this.startCanvas();
  },
  methods: {
    /**
     * 波浪图配置
     * */
    startCanvas() {
      //录音波浪
      this.oCanvas = document.getElementById('canvas');
      this.ctx = this.oCanvas.getContext("2d");
      //播放波浪
      this.pCanvas = document.getElementById('playChart');
      this.pCtx = this.pCanvas.getContext("2d");
    },
    /**
     *  录音的具体操作功能
     * */
    // 开始录音
    startRecorder() {
      //清除波浪
      this.pCanvas = document.getElementById('playChart');
      this.pCtx = this.pCanvas.getContext("2d");
      this.pCtx.clearRect(0, 0, canvas.width, canvas.height);
      Recorder.getPermission().then(() => {
        recorder.start().then(() => {
          this.drawRecord();//开始绘制图片
          this.message = "";
        }, (error) => {
          this.msgError(`${error.name} : ${error.message}`);
          return false;
        });
      }, (error) => {
        this.msgError("当前设备没有或没打开麦克风，请保持打开麦克风后开始录音!");
        return false;
      });

    },
    // 结束录音
    stopRecorder() {
      recorder.stop();

      this.fullscreenLoading = true;
      let wav = recorder.getWAVBlob();//获取 WAV 数据
      const formData = new FormData();
      formData.append('file', wav, 'filename.wav'); // 'filename.wav' 是你想要设置的文件名
      VoiceUploadfiles(formData).then((res) => {
        this.fullscreenLoading = false;
        if (res.code == 200) {
          this.message = res.msg;
        } else {
          this.msgError(res.msg);
        }

        this.destroyRecorder();
      }).catch(error => {
        this.fullscreenLoading = false;
      });
    },
    // 录音播放
    playRecorder() {
      recorder.play();
      this.drawPlay();//绘制波浪图
    },
    // 停止录音播放
    stopPlayRecorder() {
      recorder.stopPlay();
    },
    // 销毁录音
    destroyRecorder() {
      recorder.destroy().then(function () {
        recorder = null;
        this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
        this.drawRecordId = null;
      });
    },
    /**
     *  获取录音文件
     * */
    getRecorder() {
      let toltime = recorder.duration;//录音总时长
      let fileSize = recorder.fileSize;//录音总大小
      //录音结束，获取取录音数据
      let PCMBlob = recorder.getPCMBlob();//获取 PCM 数据
      let wav = recorder.getWAVBlob();//获取 WAV 数据
      let channel = recorder.getChannelData();//获取左声道和右声道音频数据
    },
    /**
     * 绘制波浪图-录音
     * */
    drawRecord() {
      // 用requestAnimationFrame稳定60fps绘制
      this.drawRecordId = requestAnimationFrame(this.drawRecord);
      // 实时获取音频大小数据
      let dataArray = recorder.getRecordAnalyseData(),
        bufferLength = dataArray.length;
      // 填充背景色
      this.ctx.fillStyle = 'rgb(200, 200, 200)';
      this.ctx.fillRect(0, 0, this.oCanvas.width, this.oCanvas.height);
      // 设定波形绘制颜色
      this.ctx.lineWidth = 2;
      this.ctx.strokeStyle = 'rgb(0, 0, 0)';
      this.ctx.beginPath();
      var sliceWidth = this.oCanvas.width * 1.0 / bufferLength, // 一个点占多少位置，共有bufferLength个点要绘制
        x = 0;          // 绘制点的x轴位置
      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = v * this.oCanvas.height / 2;
        if (i === 0) {
          // 第一个点
          this.ctx.moveTo(x, y);
        } else {
          // 剩余的点
          this.ctx.lineTo(x, y);
        }
        // 依次平移，绘制所有点
        x += sliceWidth;
      }
      this.ctx.lineTo(this.oCanvas.width, this.oCanvas.height / 2);
      this.ctx.stroke();
    },
    /**
     * 绘制波浪图-播放
     * */
    drawPlay() {
      // 用requestAnimationFrame稳定60fps绘制
      this.drawPlayId = requestAnimationFrame(this.drawPlay);
      // 实时获取音频大小数据
      let dataArray = recorder.getPlayAnalyseData(),
        bufferLength = dataArray.length;
      // 填充背景色
      this.pCtx.fillStyle = 'rgb(200, 200, 200)';
      this.pCtx.fillRect(0, 0, this.pCanvas.width, this.pCanvas.height);
      // 设定波形绘制颜色
      this.pCtx.lineWidth = 2;
      this.pCtx.strokeStyle = 'rgb(0, 0, 0)';
      this.pCtx.beginPath();
      var sliceWidth = this.pCanvas.width * 1.0 / bufferLength, // 一个点占多少位置，共有bufferLength个点要绘制
        x = 0;          // 绘制点的x轴位置
      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = v * this.pCanvas.height / 2;
        if (i === 0) {
          // 第一个点
          this.pCtx.moveTo(x, y);
        } else {
          // 剩余的点
          this.pCtx.lineTo(x, y);
        }
        // 依次平移，绘制所有点
        x += sliceWidth;
      }
      this.pCtx.lineTo(this.pCanvas.width, this.pCanvas.height / 2);
      this.pCtx.stroke();
    }
  },
}
</script>
<style lang="scss" scoped>
.box-card {
  height: calc(100vh - 105px);
  padding: 10px 20px 20px 20px;
}

.card-header {
  display: flex;
  justify-content: center;
  padding: 5px;
}

.card-wenzi-item {
  border-radius: 5px;
  border: 1px solid #ddd;
  height: 400px;
  overflow-y: auto;
  padding: 16px;
}

::v-deep .el-card .el-card__header {
  padding-bottom: 15px;
}
</style>